<script setup lang="ts">
import { reactive, ref } from 'vue'
import { type FormInstance, type FormRules, ElMessage } from 'element-plus'

import { useUserStore } from '@/store/modules/user'
import { IPutPassword } from '@/api/login/type'
import { putPassword } from '@/api/login/user'

interface IDialogState {
  visible: boolean
  title: string
}

interface IDialogForm {
  oldPassword: string
  newPassword: string
  checkPassword: string
}

const emits = defineEmits(['updatePwd'])

// 弹窗信息
const dialogState = reactive<IDialogState>({
  visible: false,
  title: '修改密码'
})

// 弹窗表单
const dialogForm = reactive<IDialogForm>({
  // 旧密码
  oldPassword: '',
  // 新密码
  newPassword: '',
  // 确认密码
  checkPassword: ''
})

const userStore = useUserStore()

// 密码校验-正则表达式
const REGULAR_PASSWORD = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z!@#$%^&*]{6,18}$/
// 新密码——自定义校验规则
const validateNewPasswordRules = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入新密码'))
  } else {
    if (!REGULAR_PASSWORD.test(value)) {
      callback(new Error('密码长度应为6至18位，并且必须包含大小写字母和数字'))
    } else {
      callback()
    }
  }
}
// 确认密码——自定义校验规则
const validatePasswordRules = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请确认密码'))
  } else {
    if (!REGULAR_PASSWORD.test(value)) {
      callback(new Error('密码长度应为6至18位，并且必须包含大小写字母和数字'))
    } else {
      if (dialogForm.newPassword === dialogForm.checkPassword) {
        callback()
      } else {
        callback(new Error('新密码与确认密码不一致'))
      }
    }
  }
}
// 表单校验
const rules: FormRules = {
  oldPassword: [{ required: true, message: '请输入旧密码', trigger: 'blur' }],
  newPassword: [{ validator: validateNewPasswordRules, trigger: 'change', required: true }],
  checkPassword: [{ validator: validatePasswordRules, trigger: 'change', required: true }]
}

/**
 * 显示弹框
 */
const showDialog = () => {
  dialogState.visible = true
}
// 表单元素
const dialogFormRef = ref<FormInstance>()

/**
 * 提交表单
 * @param formEl 表单元素
 */
const handleSubmit = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(async valid => {
    if (valid) {
      const userId = userStore.getUserInfo.userId as number
      const sendData: IPutPassword = {
        userId,
        oldPassword: dialogForm.oldPassword,
        newPassword: dialogForm.newPassword
      }
      const res = await putPassword(sendData)
      if (res.msg === '成功') {
        ElMessage.success('密码修改成功，请重新登录')
        emits('updatePwd')
      }
    }
  })
}

/**
 * 关闭弹框
 * @param formEl 表单元素
 */
const handleClose = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
  dialogState.visible = false
}

defineExpose({ showDialog })
</script>

<template>
  <tme-dialog
    v-model="dialogState.visible"
    :title="dialogState.title"
    dialog-width="25%"
    max-height="200px"
    @close="handleClose(dialogFormRef)"
    front-icon="edit"
  >
    <el-form ref="dialogFormRef" :model="dialogForm" :rules="rules" :label-width="100">
      <el-form-item prop="oldPassword" label="旧密码">
        <el-input v-model="dialogForm.oldPassword" type="password" placeholder="请输入旧密码" show-password />
      </el-form-item>
      <el-form-item prop="newPassword" label="新密码">
        <el-input v-model="dialogForm.newPassword" type="password" placeholder="请输入新密码" show-password />
      </el-form-item>
      <el-form-item prop="checkPassword" label="确认密码">
        <el-input v-model="dialogForm.checkPassword" type="password" placeholder="请确认密码" show-password />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="handleClose(dialogFormRef)" size="large">取消</el-button>
      <el-button type="primary" @click="handleSubmit(dialogFormRef)" size="large">提交</el-button>
    </template>
  </tme-dialog>
</template>
